package cn.edu.bit.dm;

import java.util.LinkedList;

public class ThreadPool extends ThreadGroup {
	
	
	private boolean isClosed=false;     //线程池是否关闭
	private LinkedList<Runnable> workQueue;   //表示工作队列
	private static int threadPoolID;     //表示线程池ID
	private int threadID;      //表示工作线程ID
	
	
	public ThreadPool(int poolSize) {
		super("ThreadPool-" + (threadPoolID++));
		setDaemon(true);
		workQueue = new LinkedList<Runnable>();
		for (int i=0; i<poolSize; i++){
			new WorkThread().start();
		}
	}
	
	public synchronized void execute(Runnable task) {
		if (isClosed) {
			throw new IllegalStateException();
		}
		if (task != null) {
			workQueue.add(task);
			notify();
		}
	}
	
	/** 从工作队列中取出一个任务，工作线程会调用此方法 */
	protected Runnable getTask()throws InterruptedException{
		synchronized (this) {
			while (workQueue.size() == 0) {
				if (isClosed) return null;
				wait();       //如果工作队列中没有任务，就等待任务
			}
			return (Runnable)workQueue.removeFirst();
		}
	}
	
	/** 关闭线程池 */
	public synchronized void close() {
		if (!isClosed) {
			isClosed = true;
			workQueue.clear();
			interrupt();       //中断所有的工作线程，该方法继承自ThreadGroup类
		}
	}
	
	
	/** 等待工作线程把所有任务执行完 */
	public void join(){
		synchronized (this) {
			isClosed = true;
			notifyAll();       //唤醒还在getTask()方法中等待任务的工作线程
		}
		Thread[] threads = new Thread[activeCount()];
		//enumerate()方法继承自ThreadGroup类，获得线程组中当前所有活着的工作线程
		int count = enumerate(threads);
		for (int i=0; i<count; i++){
			try {
				threads[i].join();     //等待工作线程运行结束
			}catch(InterruptedException ex) {
				//do nothing...
			}
		}
	}
	
	/**  内部类：工作线程  */
	private class WorkThread extends Thread {
		
		public WorkThread() {
			super(ThreadPool.this,"WorkThread-" + (threadID++));
		}
		
		public void run() {
				while (!isInterrupted()) {  
					//isInterrupted()方法继承自Thread类，判断线程是否被中断
					Runnable task = null;
					try {      
						task = getTask();
					}catch (InterruptedException ex){}
					
					// 如果getTask()返回null或者线程执行getTask()时被中断，则结束此线程
					if (task == null) return;
					try {
						task.run();
					} catch (Throwable t) {
						t.printStackTrace();
					}
				}   
		}
	}
}